package com.py.credit.service.excel.read.service.impl;

import com.py.credit.common.logs.ExceptionLogger;
import com.py.credit.dao.RuleBindingDao;
import com.py.credit.dao.RuleCheckingDao;
import com.py.credit.entity.Column;
import com.py.credit.entity.common.InspectRule;
import com.py.credit.service.excel.read.service.RuleCheckService;
import com.py.credit.service.excel.read.InspectHandles;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 规则校验实现类
 *
 * @author YaoS
 * @date 2019-04-03 10:19
 */
@Service("ruleCheckService")
public class RuleCheckServiceImpl implements RuleCheckService {

    @Autowired
    private RuleBindingDao ruleBindingDao;

    @Autowired
    private RuleCheckingDao ruleCheckingDao;

    @Override
    public Integer selectCurrentContentVersion() {
        return ruleBindingDao.selectCurrentContentVersion();
    }

    @Override
    public String ruleCheck(int tableId, Map<String, Object> map, List<Column> columns) {
        // 获取当前版本
        int editionId = ruleBindingDao.selectCurrentContentVersion();
        // 表规则校验
        String table = this.dataTableCheck(tableId, map, editionId);
        if (StringUtils.isNotBlank(table)) {
            return table;
        }
        // 字段规则校验
        String column = this.dataColumnCheck(tableId, map, columns, editionId);
        if (StringUtils.isNotBlank(column)) {
            return column;
        }
        return null;
    }

    /**
     * 功能描述: 根据当前版本对数据进行表规则校验（错误数据再入库和信用评价数据入库）
     *
     * @param tableId   表id
     * @param map       校验的数据
     * @param editionId 版本ID
     * @return 校验的结果
     * @author YaoS
     * @date 19/3/29 11:59
     */
    private String dataTableCheck(int tableId, Map<String, Object> map, Integer editionId) {
        List<InspectRule> rules = ruleCheckingDao.selctTableRules(tableId, editionId);
        StringBuilder sb = new StringBuilder(200);
        boolean validate;
        for (InspectRule isr : rules) {
            try {
                validate = InspectHandles.ruleCheckForTable(isr, map);
                if (!validate) {
                    sb.append("该记录不符合表规则").append("（").append(isr.getRuleDesc()).append("）");
                } else {
                    continue;
                }
            } catch (Exception e) {
                ExceptionLogger.error("InspectDataStyleServiceImpl#errorDataTableCheck",
                        "问题数据表规则校验异常！ERROR：" + e.getMessage(), e);
            }
        }
        return sb.toString();
    }

    /**
     * 功能描述: 根据当前版本对数据进行字段规则校验
     *
     * @param tableId   资源ID
     * @param map       待校验数据
     * @param columns   待校验字段
     * @param editionId 版本ID
     * @return 校验结果
     * @author YaoS
     * @date 19/3/29 16:55
     */
    private String dataColumnCheck(int tableId, Map<String, Object> map, List<Column> columns, Integer editionId) {
        StringBuilder sb = new StringBuilder(200);
        String dataValue;
        boolean validate;
        for (Column metric : columns) {
            dataValue = InspectHandles.dateToStr(metric, map);
            List<InspectRule> list = ruleCheckingDao.selectColumnRule(metric.getMetricCode(), editionId, tableId);
            if (list.size() > 0) {
                for (InspectRule rule : list) {
                    try {
                        validate = InspectHandles.ruleCheckForColumn(rule, dataValue);
                        if (!validate) {
                            sb.append(metric.getMetricName()).append(":").append(rule.getRuleDesc()).append(";");
                        } else {
                            continue;
                        }
                    } catch (Exception e) {
                        ExceptionLogger.error("InspectDataStyleServiceImpl#errorDataColumnCheck",
                                "字段规则数据校验异常！ERROR：" + e.getMessage(), e);
                    }
                }
            } else {
                continue;
            }
        }
        return sb.toString();
    }

}
